package com.dlc.shop.coupon.multishop.controller;


import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dlc.shop.bean.enums.OfflineHandleEventType;
import com.dlc.shop.bean.model.OfflineHandleEvent;
import com.dlc.shop.bean.param.OfflineHandleEventAuditParam;
import com.dlc.shop.bean.param.SendUserCouponsParam;
import com.dlc.shop.common.exception.YamiShopBindException;
import com.dlc.shop.common.response.ServerResponseEntity;
import com.dlc.shop.common.util.PageParam;
import com.dlc.shop.coupon.common.constants.CouponStatusEnum;
import com.dlc.shop.coupon.common.constants.ValidTimeTypeEnum;
import com.dlc.shop.coupon.common.model.Coupon;
import com.dlc.shop.coupon.common.model.CouponUser;
import com.dlc.shop.coupon.common.param.UserCouponParam;
import com.dlc.shop.coupon.common.service.CouponService;
import com.dlc.shop.security.multishop.util.SecurityUtils;
import com.dlc.shop.service.OfflineHandleEventService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author lgh on 2018/12/27.
 */
@RestController("adminCouponController")
@RequestMapping("/admin/coupon")
@Tag(name = "商家端优惠券接口")
@AllArgsConstructor
public class CouponController {

    private final CouponService couponService;

    private final OfflineHandleEventService offlineHandleEventService;

    @GetMapping("/page")
    @PreAuthorize("@pms.hasPermission('admin:coupon:page')")
    @Operation(summary = "分页获取优惠券列表信息")
    public ServerResponseEntity<IPage<Coupon>> page(Coupon coupon, PageParam<Coupon> page) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        coupon.setShopId(shopId);
        IPage<Coupon> multiShopPage = couponService.getMultiShopPage(page, coupon);
        return ServerResponseEntity.success(multiShopPage);
    }

    @GetMapping("/info/{id}")
    @Operation(summary = "根据优惠券id获取优惠券信息")
    @Parameter(name = "id", description = "优惠券id" )
    @PreAuthorize("@pms.hasPermission('admin:coupon:info')")
    public ServerResponseEntity<Coupon> info(@PathVariable("id") Long id) {
        Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(id);
        if (!Objects.equals(SecurityUtils.getShopUser().getShopId(), coupon.getShopId())) {
            throw new YamiShopBindException("yami.no.auth");
        }
        return ServerResponseEntity.success(coupon);
    }

    @PostMapping
    @PreAuthorize("@pms.hasPermission('admin:coupon:save')")
    @Operation(summary = "新增优惠券")
    public ServerResponseEntity<Long> save(@RequestBody @Valid Coupon coupon) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        coupon.setShopId(shopId);
        coupon.setSourceStock(coupon.getStocks());
        //判断为领取后生效类型时，开始时间和结束时间为空
        if (Objects.equals(coupon.getValidTimeType(), ValidTimeTypeEnum.RECEIVE.getValue())) {
            coupon.setEndTime(null);
            coupon.setStartTime(null);
        }
        couponService.insertCouponAndCouponProds(coupon);
        return ServerResponseEntity.success(coupon.getCouponId());
    }

    @PutMapping
    @PreAuthorize("@pms.hasPermission('admin:coupon:update')")
    @Operation(summary = "修改优惠券")
    public ServerResponseEntity<Void> update(@RequestBody @Valid Coupon coupon) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        Coupon dbCoupon = couponService.getById(coupon.getCouponId());
        if (!Objects.equals(dbCoupon.getShopId(), shopId)) {
            // 没有权限修改该优惠券信息
            throw new YamiShopBindException("yami.coupon.no.auth");
        }
        if (Objects.equals(dbCoupon.getPutonStatus(), CouponStatusEnum.OFFLINE.getValue()) || Objects.equals(dbCoupon.getPutonStatus(), CouponStatusEnum.WAIT_AUDIT.getValue())) {
            // 优惠券处于违规下线或者待审核状态时，商家不能直接修改优惠券状态
            coupon.setPutonStatus(dbCoupon.getPutonStatus());
        } else if (Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.OFFLINE.getValue()) || Objects.equals(coupon.getPutonStatus(), CouponStatusEnum.WAIT_AUDIT.getValue())) {
            // 当数据库中的优惠券状态不是违规下线或者待审核状态时，如果接口传进来的优惠券状态为违规下线或者待审核状态，说明该优惠券应该已经被审核了
            // 使用数据库的优惠券状态
            coupon.setPutonStatus(dbCoupon.getPutonStatus());
        }
        coupon.setShopId(shopId);
        //被领取数量
        int receNum = dbCoupon.getSourceStock() - dbCoupon.getStocks();
        //新的原始库存
        int newSourceStock = coupon.getStocks() + receNum;
        coupon.setSourceStock(newSourceStock);
        couponService.updateCouponAndCouponProds(coupon);
        return ServerResponseEntity.success();
    }

    @DeleteMapping
    @PreAuthorize("@pms.hasPermission('admin:coupon:delete')")
    @Operation(summary = "删除优惠券")
    public ServerResponseEntity<Void> delete(@RequestBody Long couponId) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        Coupon dbCoupon = couponService.getById(couponId);
        if (!Objects.equals(dbCoupon.getShopId(), shopId)) {
            // 没有权限修改该优惠券信息
            throw new YamiShopBindException("yami.coupon.no.auth");
        }
        couponService.deleteByCouponId(couponId);
        return ServerResponseEntity.success();
    }

    @GetMapping("/getOfflineHandleEventByCouponId/{couponId}")
    @Operation(summary = "通过优惠券id获取下线信息")
    @Parameter(name = "couponId", description = "优惠券id" )
    @PreAuthorize("@pms.hasPermission('admin:coupon:offlineInfo')")
    public ServerResponseEntity<OfflineHandleEvent> getOfflineHandleEventByDiscountId(@PathVariable("couponId") Long couponId) {
        OfflineHandleEvent offlineHandleEvent = offlineHandleEventService.getProcessingEventByHandleTypeAndHandleId(OfflineHandleEventType.COUPON.getValue(), couponId);
        return ServerResponseEntity.success(offlineHandleEvent);
    }

    @PostMapping("/auditApply")
    @PreAuthorize("@pms.hasPermission('admin:coupon:auditApply')")
    @Operation(summary = "违规商品提交审核")
    public ServerResponseEntity<Void> auditApply(@RequestBody OfflineHandleEventAuditParam offlineHandleEventAuditParam) {
        Coupon coupon = couponService.getCouponAndCouponProdsByCouponId(offlineHandleEventAuditParam.getHandleId());
        if (coupon == null) {
            // 未找到该活动信息
            throw new YamiShopBindException("yami.activity.cannot.find");
        }
        couponService.auditApply(offlineHandleEventAuditParam.getEventId(), offlineHandleEventAuditParam.getHandleId(), offlineHandleEventAuditParam.getReapplyReason());
        // 移除缓存
        couponService.removeCouponAndCouponProdsCache(coupon.getShopId());
        return ServerResponseEntity.success();
    }

    @GetMapping("/listCanSendCoupon")
    @Operation(summary = "获取品牌可以发放给会员的优惠券列表")
    public ServerResponseEntity<IPage<Coupon>> listCanSendCoupon(PageParam<Coupon> page, Coupon coupon) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        PageParam<Coupon> couponList  = couponService.page(page, new LambdaQueryWrapper<Coupon>()
                .eq(Coupon::getShopId, shopId)
                .eq(Coupon::getPutonStatus, 1)
                .eq(Coupon::getGetWay, 1)
                .like(StrUtil.isNotBlank(coupon.getCouponName()), Coupon::getCouponName, coupon.getCouponName())
                .orderByDesc(Coupon::getCouponId));;
        return ServerResponseEntity.success(couponList);
    }

    @PutMapping("/sendUserCoupon")
    @Operation(summary = "品牌批量发放优惠券给会员")
    @PreAuthorize("@pms.hasPermission('admin:coupon:send')")
    public ServerResponseEntity<Boolean> sendUserCoupon(@RequestBody UserCouponParam param) {
//        if (!Objects.equals(SecurityUtils.getShopUser().getSysType(), SysTypeEnum.BRAND.value())) {
//            // 没有权限修改该优惠券信息
//            throw new YamiShopBindException("yami.coupon.no.auth");
//        }
        Long shopId = SecurityUtils.getShopUser().getShopId();
        List<String> userIds = param.getUserIds();
        if (CollectionUtils.isEmpty(userIds)) {
            return ServerResponseEntity.success();
        }
        List<SendUserCouponsParam> coupons = param.getCoupons();
        if (CollectionUtils.isEmpty(coupons)) {
            return ServerResponseEntity.success();
        }
        for (String userId : userIds) {
            Map<Long, Integer> couponMap = coupons.stream().collect(Collectors.toMap(SendUserCouponsParam::getCouponId, SendUserCouponsParam::getNums));
            couponService.batchBindCouponByIds(couponMap, userId, shopId);
        }
        return ServerResponseEntity.success();
    }

    @GetMapping("/pageByUserId")
    @Operation(summary = "获取某个用户的优惠券明细")
    @Parameters({
            @Parameter(name = "userId", description = "用户id"),
            @Parameter(name = "status", description = "优惠券状态 0:失效 1:有效 2:使用过")
    })
    @PreAuthorize("@pms.hasPermission('admin:coupon:pageByUserId')")
    public ServerResponseEntity<IPage<CouponUser>> getPageByUserId(PageParam<CouponUser> page, String userId, Integer status) {
        Long shopId = SecurityUtils.getShopUser().getShopId();
        IPage<CouponUser> resPage = couponService.getPageByUserId(page, userId, status, shopId);
        return ServerResponseEntity.success(resPage);
    }
}
